Dispatch once in Swift using a handy trick
Switch allows to declare a type inside a function body. This ability could be handy in some situations. I found it useful to run the body of the function only once. For example we use to run only once the body of the function updateConstraints(). In addition to that, if we use static variable in the inner struct Swift gives us thread safety for free. I have created a simple wrapper, that allows to run an action and be sure that it will be run only once, even in the concurrect scenario.
struct Once {
func run(action: () -> Void) {
struct RunCheck {
static var didRun = false
}
guard !RunCheck.didRun else { return }
RunCheck.didRun = true
action()
}
}
Example of use:
let once = Once()
var indexes: [Int] = []
DispatchQueue.concurrentPerform(iterations: 100, execute: { index in
once.run {
indexes.append(index)
}
})
print(indexes) // It will have only one element